/*
 * CommunicationVendedor.cpp
 *
 */

#include "CommunicationVendedor.h"
#include "../logger/logger.h"

namespace middleware {

const std::string CommunicationVendedor::REQUEST_QUEUE_PATH = "/tmp/vendedor";
const std::string CommunicationVendedor::REPLY_QUEUE_PATH  = "/tmp/vendedor";
const std::string CommunicationVendedor::AVAILABLE_QUEUE_PATH  = "/tmp/vendedor";
const std::string CommunicationVendedor::VENDEDORID_SEQUENCE_PATH = "/tmp/vendedor";
const std::string CommunicationVendedor::OC_ID_SEQUENCE_PATH = "/tmp/vendedor";

CommunicationVendedor::CommunicationVendedor()
			:m_RequestQueue(ipc::MessageQueue<VendedorRequestStruct>::
									get(REQUEST_QUEUE_PATH,REQUEST_QUEUE_KEY)),
			 m_ReplyQueue(ipc::MessageQueue<VendedorReplyStruct>::
									get(REPLY_QUEUE_PATH,REPLY_QUEUE_KEY)),
		     m_AvailableVendedor(ipc::MessageQueue<AvailableVendedorStruct>::
		    		 	 	 	 	get(AVAILABLE_QUEUE_PATH,AVAILABLE_QUEUE_KEY)),
			 m_vendedorIdGenerator(ipc::Sequence::get(VENDEDORID_SEQUENCE_PATH,VENDEDORID_SEQUENCE_KEY)),
			 m_ordenCompraIdGenerator(ipc::Sequence::get(OC_ID_SEQUENCE_PATH,OC_ID_SEQUENCE_KEY))
{

}

CommunicationVendedor::~CommunicationVendedor()
{
}

int CommunicationVendedor::generateVendedorId()
{
	return m_vendedorIdGenerator.getNext();
}


void CommunicationVendedor::avisarVendedorDisponible(int vendedorId)
{
	AvailableVendedorStruct message;

	message.vendedorId = vendedorId;

	m_AvailableVendedor.put(1,message);
}

int CommunicationVendedor::getVendedorId()
{
	AvailableVendedorStruct vendedorRequest;

	vendedorRequest = m_AvailableVendedor.get(1);

	return vendedorRequest.vendedorId;
}

int CommunicationVendedor::sendOrdenCompra(OrdenCompra &ordenCompra)
{
	bool retVal = false;
	ProductoCantidadList::iterator it;
	VendedorReplyStruct vendedorReply;
	VendedorRequestStruct vendedorFinalRequest;

	for(it=ordenCompra.productos.begin(); it != ordenCompra.productos.end(); it++)
	{
		VendedorRequestStruct vendedorRequest;
		vendedorRequest.requestType = ITEM_ORDEN_COMPRA;
		vendedorRequest.producto= *it;
		vendedorRequest.ordenCompra = ordenCompra.header;

		m_RequestQueue.put(ordenCompra.header.vendedorId,vendedorRequest);
		CLogger::log("Pedido de producto enviado", LogLevelEnum::TRACE);
	}

	vendedorFinalRequest.requestType = FIN_ORDEN_COMPRA;
	vendedorFinalRequest.ordenCompra = ordenCompra.header;
	m_RequestQueue.put(ordenCompra.header.vendedorId,vendedorFinalRequest);

	CLogger::log("Fin orden de compra", LogLevelEnum::TRACE);

	vendedorReply = m_ReplyQueue.get(ordenCompra.header.clientId);

	if(vendedorReply.status == OC_OK)
		retVal = true;

	return retVal;
}

void CommunicationVendedor::receiveOrdenCompra(int vendedorId,int &clientId,
													 ProductoCantidad &producto,
													 OrdenCompraHeader &ordenCompra,
													 bool &ordenCompraEnded)
{
	VendedorRequestStruct vendedorRequest;

	vendedorRequest = m_RequestQueue.get(vendedorId);
	clientId = vendedorRequest.ordenCompra.clientId;
	ordenCompra = vendedorRequest.ordenCompra;

	if(vendedorRequest.requestType == ITEM_ORDEN_COMPRA)
	{
		producto = vendedorRequest.producto;
		CLogger::log("Se recibio pedido de un item", LogLevelEnum::TRACE);
		ordenCompraEnded=false;
	}
	else
	{
		if(vendedorRequest.requestType == FIN_ORDEN_COMPRA)
		{
			producto.cantidad =0;
			producto.tipo =0;
			ordenCompraEnded = true;
		}
		else
			throw Exception("Wrong request type received");
	}

}

void CommunicationVendedor::respondOrdenCompra(int clientId,OrdenCompraStatus status)
{
	VendedorReplyStruct vendedorReply;
	vendedorReply.status = status;

	m_ReplyQueue.put(clientId,vendedorReply);
}

int CommunicationVendedor::generateOrdenCompraId()
{
	return m_ordenCompraIdGenerator.getNext();
}

void CommunicationVendedor::create()
{
	ipc::MessageQueue<VendedorRequestStruct>::create(REQUEST_QUEUE_PATH,REQUEST_QUEUE_KEY);
	ipc::MessageQueue<VendedorReplyStruct>::create(REPLY_QUEUE_PATH,REPLY_QUEUE_KEY);
	ipc::MessageQueue<AvailableVendedorStruct>::create(AVAILABLE_QUEUE_PATH,AVAILABLE_QUEUE_KEY);
	ipc::Sequence::create(VENDEDORID_SEQUENCE_PATH,VENDEDORID_SEQUENCE_KEY);
	ipc::Sequence::create(OC_ID_SEQUENCE_PATH,OC_ID_SEQUENCE_KEY);
}

void CommunicationVendedor::destroy()
{
	ipc::MessageQueue<VendedorRequestStruct>::destroy(REQUEST_QUEUE_PATH,REQUEST_QUEUE_KEY);
	ipc::MessageQueue<VendedorReplyStruct>::destroy(REPLY_QUEUE_PATH,REPLY_QUEUE_KEY);
	ipc::MessageQueue<AvailableVendedorStruct>::destroy(AVAILABLE_QUEUE_PATH,AVAILABLE_QUEUE_KEY);
	ipc::Sequence::destroy(VENDEDORID_SEQUENCE_PATH,VENDEDORID_SEQUENCE_KEY);
	ipc::Sequence::destroy(OC_ID_SEQUENCE_PATH,OC_ID_SEQUENCE_KEY);
}

} /* namespace middleware */

